﻿using Abp.Dependency;
using HCD.Web.Authorizer;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace HCD.Web.Hubs
{
    /// <summary>
    /// 集线器 2018.8.8 add by yz
    /// </summary>
    public class SystemHub : Hub
    {
        /// <summary>
        /// 在线人员池
        /// </summary>
        public static IDictionary<string, string> Pool = new ConcurrentDictionary<string, string>();
        // private readonly IConfiguration _configuration;
        //private readonly bool multilogin = bool.Parse(System.Configuration.ConfigurationManager.AppSettings["ConcurrentLoginEnabled"] ?? "true");
        private readonly IHubContext<SystemHub> _hubContext;
        /// <summary>
        /// constructor
        /// </summary>
        public SystemHub(IHubContext<SystemHub> HubContext)
        {
            _hubContext = HubContext;
        }

        /// <summary>
        /// 初始化连接
        /// </summary>
        /// <returns></returns>
        public override Task OnConnectedAsync()
        {
            //var secretkey = _configuration["Customization:JwtKey"];
            var cid = Context.ConnectionId;
            if (Context.GetHttpContext().Request.Cookies.TryGetValue("ck_token", out string token))
            {
                var auth = JWTUtil.DecodeToken(token);
                var uid = auth.EmpNo;
                //踢用户
                var userOnlie = Pool.Where(p => p.Value == uid).ToList();
                userOnlie?.ForEach(p =>
                {
                    _hubContext.Clients.Client(p.Key).SendAsync("execute", "location.href = '/Home/LogOut';");
                    Pool.Remove(p.Key);
                });
                if (userOnlie?.Count < 1)//首次上线
                {
                    //提示用户上线
                    var userOtherOnlie = Pool.Where(p => p.Value != uid).ToList();
                    userOtherOnlie?.ForEach(p =>
                    {
                        _hubContext.Clients.Client(p.Key).SendAsync("online", auth.Name);
                    });
                }
                Pool.TryAdd(cid, uid);
                _hubContext.Clients.Client(cid).SendAsync("oninfo", auth.Name);
                return base.OnConnectedAsync();
            }
            throw new Exception("身份错误");
        }

        /// <summary>
        /// 断开
        /// </summary>
        /// <param name="exception"></param>
        /// <returns></returns>
        public override Task OnDisconnectedAsync(Exception exception)
        {
            if (Context.GetHttpContext().Request.Cookies.TryGetValue("ck_token", out string token))
            {
                var auth = JWTUtil.DecodeToken(token);
                var uid = auth.EmpNo;
                //提示用户断线
                Pool.ToList()?.ForEach(p =>
                {
                    _hubContext.Clients.Client(p.Key).SendAsync("offline", auth.Name);
                });
            }
            Pool.Remove(Context.ConnectionId);
            return base.OnDisconnectedAsync(exception);
        }
    }
}